package com.opages.netty.demo.netty.chat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * @author daizhong.liu
 * @create 2021-12-09 17:21
 **/
public class ServerChatChannel extends SimpleChannelInboundHandler<String> {
    private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        //发送者
        Channel channel = ctx.channel();
        channels.stream().forEach(c -> {
            if(channel != c) {
                c.writeAndFlush("用户【"+channel.remoteAddress()+"】:"+msg);
            }else {
                c.writeAndFlush("我说:"+msg);
            }
        });
    }

    //表示channel 处于活动状态, 提示 xx上线
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println(ctx.channel().remoteAddress()+"上线.");
    }
    //表示channel 处于不活动状态, 提示 xx离线了
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.err.println(ctx.channel().remoteAddress()+"离线.");
    }
    //handlerAdded 表示连接建立，一旦连接，第一个被执行
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channels.add(channel);
        channels.writeAndFlush("用户【"+channel.remoteAddress()+"】加入聊天室.");
        System.err.println("当前用户数："+channels.size());

    }
    //断开连接, 将xx客户离开信息推送给当前在线的客户
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channels.remove(channel);
        channels.writeAndFlush("用户【"+channel.remoteAddress()+"】离开了.");
        System.err.println("当前用户数："+channels.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
